package com.jsmile.cloud.authc.sys.repo;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsmile.cloud.authc.api.exception.AuthcException;
import com.jsmile.cloud.authc.api.req.sys.ReqSysResourcePageQuery;
import com.jsmile.cloud.authc.api.req.sys.ReqSysResourceQuery;
import com.jsmile.cloud.authc.api.res.ResSysResources;
import com.jsmile.cloud.authc.sys.dao.SysResourcesDao;
import com.jsmile.cloud.authc.sys.model.SysResources;
import com.jsmile.cloud.authc.sys.model.SysRole;
import com.jsmile.mall.api.enums.JSmileCodeEnum;
import com.jsmile.mall.api.kit.DateKit;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 龚亮
 * @version 1.0
 * @desc 为了薪资破万，还是睡一会儿吧...!
 * @date 2020年10月16日 02:46:20
 */
@Service
@Slf4j
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class SysResourcesSearchRepository extends ServiceImpl<SysResourcesDao, SysResources> {

    public IPage<SysResources> pageQuery(ReqSysResourcePageQuery reqSysResourceQuery) {
        return this.baseMapper.selectPage(reqSysResourceQuery.getPage(), getQueryWrapper(reqSysResourceQuery));
    }

    public List<SysResources> getList(ReqSysResourceQuery reqSysResourceQuery) {
        return this.baseMapper.selectList(getQueryWrapper(BeanUtil.toBean(reqSysResourceQuery, ReqSysResourcePageQuery.class)));
    }

    public List<ResSysResources> listToRes(ReqSysResourceQuery reqSysResourceQuery) {
        List<SysResources> resources = this.baseMapper.selectList(getQueryWrapper(BeanUtil.toBean(reqSysResourceQuery, ReqSysResourcePageQuery.class)));
        if (CollectionUtils.isEmpty(resources))
            return null;
        return resources.stream().map(x -> BeanUtil.toBean(x, ResSysResources.class)).collect(Collectors.toList());
    }

    private Wrapper getQueryWrapper(ReqSysResourcePageQuery reqSysResourceQuery) {
        Optional.ofNullable(reqSysResourceQuery.getCurTenantId()).orElseThrow(() -> new AuthcException(JSmileCodeEnum.TENANT_ID_NOT_NULL));
        return new QueryWrapper<SysResources>().lambda().le(null != reqSysResourceQuery.getLeLevel(), SysResources::getLevel, reqSysResourceQuery.getLeLevel())
            .ge(null != reqSysResourceQuery.getGeLevel(), SysResources::getLevel, reqSysResourceQuery.getGeLevel())
            .eq(null != reqSysResourceQuery.getParentId(), SysResources::getParentId, reqSysResourceQuery.getParentId())
            .eq(null != reqSysResourceQuery.getMenuType(), SysResources::getMenuType, reqSysResourceQuery.getMenuType())
            .eq(null != reqSysResourceQuery.getEnable(), SysResources::getEnable, reqSysResourceQuery.getEnable())
            .eq(Objects.nonNull(reqSysResourceQuery.getCurTenantId()), SysResources::getTenantId, reqSysResourceQuery.getCurTenantId())
            .like(Objects.nonNull(reqSysResourceQuery.getName()), SysResources::getName, reqSysResourceQuery.getName())
            .ge(null != reqSysResourceQuery.getStartDate(), SysResources::getCreateTime,
                null == reqSysResourceQuery.getStartDate() ? null : DateKit.beginOfDay(reqSysResourceQuery.getStartDate()))
            .le(null != reqSysResourceQuery.getEndDate(), SysResources::getCreateTime,
                null == reqSysResourceQuery.getEndDate() ? null : DateKit.endOfDay(reqSysResourceQuery.getEndDate()))
            .ge(null != reqSysResourceQuery.getStartTime(), SysResources::getCreateTime, reqSysResourceQuery.getStartTime())
            .le(null != reqSysResourceQuery.getEndTime(), SysResources::getCreateTime, reqSysResourceQuery.getEndTime()).orderByAsc(SysResources::getSort)
            .orderByDesc(SysResources::getCreateTime);// sort,createTime倒序
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public List<ResSysResources> getMenuByRoleIds(Integer menuType, List<SysRole> roles, int leaf) {
        List<SysResources> resources = this.baseMapper.getMenuByRoleIds(menuType, roles, leaf);
        if (CollectionUtils.isEmpty(resources))
            return null;
        return resources.stream().map(x -> BeanUtil.toBean(x, ResSysResources.class)).collect(Collectors.toList());
    }

    /**
     * desc:根据parentId获取子节点最大sort
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public SysResources getMaxMenu(SysResources resources) {
        SysResources menu = this.baseMapper.getMaxMenu(resources);
        menu = null == menu ? new SysResources() : menu;
        if (null != resources.getParentId()) {
            menu.setParentId(resources.getParentId());
        }
        menu.setLevel(resources.getLevel() + 1);
        if (null == menu.getSort()) {
            if (1 == menu.getLevel()) {
                menu.setSort(1);
            } else if (2 == menu.getLevel()) {
                menu.setSort(11);
            } else if (3 == menu.getLevel()) {
                menu.setSort(101);
            } else if (4 == menu.getLevel()) {
                menu.setSort(1001);
            }
        } else {
            menu.setSort(menu.getSort() + 1);
        }

        return menu;
    }
}
